function Signal = generateSignal(SigStruct, MWCStruct,Npts,Tgrid)
% This function takes a structure defining the parameters of the signal,
% and generate another structure which determine the values of the signal
% (analytically).

Signal = struct;

% embed the structure
Signal = setfield(Signal, 'Structure', SigStruct); %#ok<*SFLD>

% draw/update values
Values = struct;

N = getfield(SigStruct, 'N');
B = getfield(SigStruct, 'B');
fmax = getfield(SigStruct, 'fmax');

%% Case the signal is sinc
if (strmatch(getfield(SigStruct,'Type'), 'sinc'))
    if (strmatch(getfield(SigStruct,'SincEnergies'), 'random'))
        Energies = DrawUniform([N/2 1],1,3);
    elseif (strmatch(getfield(SigStruct,'SincEnergies'), 'specify'))
        EnergiesStr = getfield(SigStruct,'SincEnergiesString');
        Energies = str2num(EnergiesStr);
    end
    Values = setfield(Values, 'SincEnergies', Energies);  
    SignalDuration = Npts*Tgrid;
    Values = setfield(Values, 'SignalDuration', SignalDuration);    
    if (strmatch(getfield(SigStruct,'SincDelays'), 'random'))
        Delays = DrawUniform([N/2 1],0,SignalDuration);
    elseif (strmatch(getfield(SigStruct,'SincDelays'), 'specify'))
        DelayString = getfield(SigStruct,'SincDelayString');
        Delays = str2num(DelayString);
    end
    Values = setfield(Values, 'SincDelays', Delays);
    
%% Case the signal is bpsk
elseif (strmatch(getfield(SigStruct,'Type'), 'bpsk'))
%     NumSymbols = getfield(SigStruct, 'BPSK_NumSymbols');
%     BitStream = RandSource(N/2,NumSymbols);
%     Values = setfield(Values, 'BitStream', BitStream);
    if (strmatch(getfield(SigStruct,'BPSKEnergies'), 'random'))
        Energies = DrawUniform([N/2 1],1,3);
    elseif (strmatch(getfield(SigStruct,'BPSKEnergies'), 'specify'))
        EnergiesStr = getfield(SigStruct,'BPSKEnergiesString');
        Energies = str2num(EnergiesStr);
    end
    Values = setfield(Values, 'BPSKEnergies', Energies);
    Tsymbol = getfield(SigStruct,'BPSK_Tsymbol');
%     Values = setfield(Values, 'SignalDuration', NumSymbols*Tsymbol);   
    
%% Case the signal is bpsk
elseif (strmatch(getfield(SigStruct,'Type'), 'qpsk'))
    if (strmatch(getfield(SigStruct,'QPSKEnergies'), 'random'))
        Energies = DrawUniform([N/2 1],1,3);
    elseif (strmatch(getfield(SigStruct,'QPSKEnergies'), 'specify'))
        EnergiesStr = getfield(SigStruct,'QPSKEnergiesString');
        Energies = str2num(EnergiesStr);
    end
    Values = setfield(Values, 'QPSKEnergies', Energies);
    Tsymbol = getfield(SigStruct,'QPSK_Tsymbol');

%% Case the signal is cosine %ETGAR
elseif (strmatch(getfield(SigStruct,'Type'), 'cosine'))
    if (strmatch(getfield(SigStruct,'CosineEnergies'), 'random'))
        Energies = DrawUniform([N/2 1],1,3);
    elseif (strmatch(getfield(SigStruct,'CosineEnergies'), 'specify'))
        EnergiesStr = getfield(SigStruct,'CosineEnergiesString');
        Energies = str2num(EnergiesStr);
    end
    Values = setfield(Values, 'CosineEnergies', Energies);  
    SignalDuration = Npts*Tgrid;
    Values = setfield(Values, 'SignalDuration', SignalDuration);    
    if (strmatch(getfield(SigStruct,'CosineDelays'), 'random'))
        Delays = DrawUniform([N/2 1],0,SignalDuration);
    elseif (strmatch(getfield(SigStruct,'CosineDelays'), 'specify'))
        DelayString = getfield(SigStruct,'CosineDelaysString');
        Delays = str2num(DelayString);
    end
    Values = setfield(Values, 'CosineDelays', Delays);
end

% Carriers
if (strmatch(getfield(SigStruct, 'Carriers'), 'random'))
    
    while(1)  %% the loop ensures that the carriers that are selected do not overlap
    Carriers = DrawUniform([N/2 1],B,fmax-B);
        if( ~sum(abs(diff(Carriers))  < B/2 ))
            break;
        end
    
    end  
elseif (strmatch(getfield(SigStruct, 'Carriers'), 'specify'))
    Carriers = str2num(getfield(SigStruct, 'CarrierString'));

elseif (strmatch(getfield(SigStruct, 'Carriers'), 'special'))
     Carriers = pseudoRandomCarriers(MWCStruct.fp,N,MWCStruct.L ); 
end
Values = setfield(Values, 'Carriers', Carriers);

% Get the state of the random generator, so that can reproduce the same
% noise in repeated simulations. however, if pressing GenerateSignal again,
% the noise is also changed (by taking a new state).
% The reason for saving the state (rather than the actual noise signal)
% since we don't know yet the resolution of the signal, which depends on
% the parameters of the next stages.
 
Values = setfield(Values, 'SavedRandomStateForNoiseGen', rng('shuffle'));

Signal = setfield(Signal, 'Values', Values); %#ok<*SFLD>

